from abc import abstractmethod, ABC
from datetime import datetime
from typing import Optional, List

from .abstract_logger import AbstractLogger


class CommonLogger(AbstractLogger):

    def debug(self, msg: str, /, **kwargs):
        return self.log(1, msg, **kwargs)

    def info(self, msg: str, /, **kwargs):
        return self.log(2, msg, **kwargs)

    def warn(self, msg: str, /, **kwargs):
        return self.log(3, msg, **kwargs)

    def error(self, msg: str, /, **kwargs):
        return self.log(4, msg, **kwargs)

    def fatal(self, msg: str, /, **kwargs):
        return self.log(5, msg, **kwargs)

    @abstractmethod
    def log(self, level: int, msg: str, **kwargs):
        pass


class LogWriter(ABC):
    @abstractmethod
    def log(self, level: int, msg: str, date: datetime, path: List[str]):
        pass


class TreeLogger(CommonLogger):
    path: List[str]
    writers: List[LogWriter]

    def __init__(self, path: List[str], writers: List[LogWriter]):
        self.path = path
        self.writers = writers

    def log(self, level: int, msg: str, **kwargs):
        if len(self.writers) == 0:
            return

        now = datetime.now()
        group: Optional[str] = kwargs.get("group")

        if group is None:
            path = self.path
            ret = self
        else:
            path = self.path + [group]
            ret = TreeLogger(path, self.writers)

        for writer in self.writers:
            writer.log(level, msg, now, path)

        return ret






